/*
DB Autobackuper plugin for Miranda IM

Copyright (C) 2005-2012 chaos.persei, sje, Kildor, Billy_Bons, Vasilich, Nikolay Raspopov

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "stdafx.h"
#include "options.h"

MM_INTERFACE	mmi = {};
HINSTANCE		hInst = NULL;
PLUGINLINK*		pluginLink = NULL;
int				hLangpack = 0;
HANDLE			hFolder = NULL;
HANDLE			hHooks[4] = {};
HANDLE			hServices[3] = {};

static const PLUGININFOEX pluginInfo =
{
	sizeof( PLUGININFOEX ),
	__PLUGIN_NAME,
	__VERSION_DWORD,
	__PLUGIN_DESC,
	__AUTHORS,
	__EMAIL,
	__COPYRIGHTS,
	__URL,
	UNICODE_AWARE,
	0,		//doesn't replace anything built-in
    // Generate your own unique id for your plugin.
    // Do not use this UUID!
    // Use uuidgen.exe to generate the uuuid
    // {81C220A6-0226-4ad6-BFCA-217B17A16053}
	MIID_DB_AUTOBACKUPS
};

static const MUUID pluginInterfaces[] = 
{
	MIID_DB_AUTOBACKUPS,
	MIID_LAST
};

struct
{
	TCHAR* szDescr;
	char* szName;
	int   defIconID;
}
static const iconList[] =
{
	{ LPGENT("Database"),	"database",	IDI_DB_AUTOBACKUPS },
	{ LPGENT("Backup NOW"),	"backup",	IDI_DB_TIME },
	{ LPGENT("Save As..."),	"saveas",	IDI_DB_SAVE }
};

static INT_PTR BackupServiceTrgr(WPARAM wParam, LPARAM /*lParam*/)
{
	if ( wParam & ACT_PERFORM )
		mir_forkthread( BackupThread, NULL );

	return 0;
}

static int FoldersGetBackupPath(WPARAM /*wParam*/, LPARAM /*lParam*/) 
{
	FoldersGetCustomPathT( hFolder, options.folder, MAX_PATH, DIR SUB_DIR );

	SaveOptions();

	return 0;
}

static int ModulesLoad(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
	TCHAR tszFile[MAX_PATH] = {};
	GetModuleFileName( hInst, tszFile, MAX_PATH );

	SKINICONDESC sid = {};
	sid.cbSize = sizeof( SKINICONDESC );
	sid.ptszDefaultFile = tszFile;
	sid.ptszSection = _T("Database/Database Backups");
	sid.flags = SIDF_ALL_TCHAR;

	for ( int i = 0; i < SIZEOF( iconList ); ++i )
	{
		sid.pszName = iconList[i].szName;
		sid.ptszDescription = iconList[i].szDescr;
		sid.iDefaultIndex = - iconList[i].defIconID;
		CallService( MS_SKIN2_ADDICON, 0, (LPARAM)&sid );
	}
	
	if ( ServiceExists( MS_FOLDERS_REGISTER_PATH ) ) 
	{
		hFolder = (HANDLE)FoldersRegisterCustomPathT( "Database Backups", "Backup Folder", DIR SUB_DIR );
		hHooks[0] = HookEvent( ME_FOLDERS_PATH_CHANGED, FoldersGetBackupPath );
	}

	LoadOptions();

	CLISTMENUITEM menu = {};
	menu.cbSize = sizeof( CLISTMENUITEM );
	menu.flags = CMIF_TCHAR;
	menu.ptszPopupName = iconList[ 0 ].szDescr;
	menu.hIcon = (HICON)CallService( MS_SKIN2_GETICON, 0, (LPARAM)iconList[ 0 ].szName );

	menu.ptszName = iconList[ 1 ].szDescr;
	menu.pszService = MS_AB_BACKUP;
	menu.position = 500100000;
	HANDLE hItem = (HANDLE)CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menu );

	menu.flags = CMIM_ICON;
	menu.hIcon = (HICON)CallService( MS_SKIN2_GETICON, 0, (LPARAM)iconList[ 1 ].szName );
	CallService( MS_CLIST_MODIFYMENUITEM, (WPARAM)hItem, (LPARAM)&menu );

	menu.flags = CMIF_TCHAR;
	menu.hIcon = (HICON)CallService( MS_SKIN2_GETICON, 0, (LPARAM)iconList[ 2 ].szName );
	menu.ptszName = iconList[ 2 ].szDescr;
	menu.pszService = MS_AB_SAVEAS;
	menu.position = 500100001;
	CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menu );

	// register trigger action for triggerplugin
	if ( ServiceExists( MS_TRIGGER_REGISTERACTION ) )
	{
		ACTIONREGISTER ar = {};
		ar.cbSize = sizeof( ACTIONREGISTER );
		ar.pszName = "Backup NOW";
		ar.pszService = MS_AB_BACKUPTRGR;
		CallService( MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar );
	}

	hHooks[1] = HookEvent( ME_OPT_INITIALISE, OptionsInit );

	if ( options.backup_types & BT_START )
	{
		mir_forkthread( BackupThread, NULL );
	}

	SetBackupTimer();

	return 0;
}

static int PreShutdown(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
	if ( options.backup_types & BT_EXIT )
	{
		options.disable_popups = 1; // Don't try to show popups on exit
		Backup( NULL );
	}

	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID /*lpvReserved*/)
{
	if ( fdwReason == DLL_PROCESS_ATTACH )
	{
		hInst = hinstDLL;
	}

	return TRUE;
}

extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD /*mirandaVersion*/)
{
	return (PLUGININFOEX*)&pluginInfo;
}

extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
{
	return pluginInterfaces;
}

extern "C" __declspec(dllexport) int Load(PLUGINLINK *link)
{
	OleInitialize( NULL );

	pluginLink = link;

	mir_getMMI( &mmi );
	mir_getLP( &pluginInfo );

	hServices[0] = CreateServiceFunction( MS_AB_BACKUP, ABService );
	hServices[1] = CreateServiceFunction( MS_AB_BACKUPTRGR, BackupServiceTrgr );
	hServices[2] = CreateServiceFunction( MS_AB_SAVEAS, DBSaveAs );

	hHooks[2] = HookEvent( ME_SYSTEM_PRESHUTDOWN, PreShutdown );
	hHooks[3] = HookEvent( ME_SYSTEM_MODULESLOADED, ModulesLoad );

	return 0;
}

extern "C" __declspec(dllexport) int Unload(void)
{
	for ( int i = 0; i < SIZEOF( hHooks ); ++i )
	{
		if ( hHooks[i] )
		{
			UnhookEvent( hHooks[i] );
			hHooks[i] = NULL;
		}
	}

	for ( int i = 0; i < SIZEOF( hServices ); ++i )
	{
		if ( hServices[i] )
		{
			DestroyServiceFunction( hServices[i] );
			hServices[i] = NULL;
		}
	}

	OleUninitialize();

	return 0;
}

void ShowPopup(LPCTSTR szText, UINT nFlags)
{
	if ( ServiceExists( MS_POPUP_ADDPOPUPT ) )
	{
		POPUPDATAT ppd = {};
		_tcscpy_s( ppd.lptzText, MAX_SECONDLINE, szText );
		_tcscpy_s( ppd.lptzContactName, MAX_CONTACTNAME, _T( __PLUGIN_NAME ) );
		ppd.lchIcon = (HICON)CallService( MS_SKIN2_GETICON, 0, (LPARAM)"backup" );
		PUAddPopUpT( &ppd );
	}
	else
	{
		MessageBox( NULL, szText, _T( __PLUGIN_NAME ), MB_OK | MB_SYSTEMMODAL | nFlags );
	}
}

int CreateDirectoryTree(LPCTSTR szDir)
{
	TCHAR szTestDir[ MAX_PATH ];
	_tcscpy_s( szTestDir, MAX_PATH, szDir );

	TCHAR* pszLastBackslash = _tcsrchr( szTestDir, _T('\\') );
	if ( pszLastBackslash == NULL )
		return 0;
	*pszLastBackslash = _T('\0');

	CreateDirectoryTree( szTestDir );

	*pszLastBackslash = _T('\\');
	return ( _tcslen( szTestDir ) > 3 && CreateDirectory( szTestDir, NULL ) == 0 ) ? GetLastError() : 0;
}

HWND CreateToolTip(HWND hwndParent, LPTSTR ptszText, LPTSTR ptszTitle)
{
	HWND hwndTT = CreateWindowEx( WS_EX_TOPMOST,
        TOOLTIPS_CLASS, NULL,
        WS_POPUP | TTS_NOPREFIX,		
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        hwndParent, NULL, hInst, NULL );

    SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0,
        SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

	TOOLINFO ti = {};
    ti.cbSize = sizeof(TOOLINFO);
    ti.uFlags = TTF_SUBCLASS | TTF_CENTERTIP;
    ti.hwnd = hwndParent;
    ti.hinst = hInst;
    ti.lpszText = ptszText;
    GetClientRect (hwndParent, &ti.rect);
	ti.rect.left -= 80;

    SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	SendMessage(hwndTT, TTM_SETTITLE, 1, (LPARAM)ptszTitle);
	SendMessage(hwndTT, TTM_SETMAXTIPWIDTH, 0, (LPARAM)700);
	return hwndTT;
} 
